home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / pro_section.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  44.3 KB  |  1,476 lines

  1. /*
  2.     pro_section.c 
  3.     $Revision: 1.46 $    $Date: 1994/06/02 17:40:25 $    
  4.     $Source: /cmplrs.src/v4.00/libdwarf/RCS/pro_section.c,v $
  5.  
  6.     This files contains routines for converting dwarf information
  7.     to disk form, and giving out bytes to be written to disk
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <sgidefs.h>
  13. #include <elfaccess.h>
  14. #include "pro_incl.h"
  15. #include "pro_section.h"
  16. #include "pro_line.h"
  17. #include "pro_frame.h"
  18. #include "pro_die.h"
  19.  
  20. static int _dwarf_pro_generate_debugline (Dwarf_P_Debug dbg, Dwarf_Error *error);
  21. static int _dwarf_pro_generate_debugframe (Dwarf_P_Debug dbg, Dwarf_Error *error);
  22. static int _dwarf_pro_generate_debuginfo (Dwarf_P_Debug dbg, Dwarf_Error *error);
  23. static Dwarf_P_Abbrev _dwarf_pro_getabbrev (Dwarf_P_Die, Dwarf_P_Abbrev);
  24. static int _dwarf_pro_match_attr
  25.     (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr);
  26. static Dwarf_P_Rel _dwarf_pro_get_new_relrec (Dwarf_P_Debug dbg);
  27. static int _dwarf_pro_rel_info (Dwarf_P_Debug dbg, Dwarf_P_Rel relrec,
  28.     Dwarf_Unsigned offset, Dwarf_Word symidx, Dwarf_Ubyte type);
  29. static int _dwarf_pro_write_reloc_section (Dwarf_P_Debug dbg, Dwarf_P_Rel rel_head,
  30.     int relsectno, int rel_nbytes, Dwarf_Error *error);
  31.  
  32. /* these macros used as return value for below functions */
  33. #define        OPC_INCS_ZERO        -1
  34. #define        OPC_OUT_OF_RANGE    -2
  35. #define        LINE_OUT_OF_RANGE    -3
  36. static int _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv);
  37.  
  38. /* names of sections. Ensure that it matches the defines 
  39.    in pro_section.h, in the same order */
  40. char *sectnames[] = {
  41.     ".debug_info",
  42.     ".debug_line",
  43.     ".debug_abbrev",
  44.     ".debug_frame",
  45.     ".debug_aranges",
  46.     ".debug_pubnames",
  47.     ".debug_str",
  48.     ".debug_funcnames",
  49.     ".debug_typenames",
  50.     ".debug_varnames",
  51.     ".debug_weaknames"
  52. };
  53.  
  54. /* arrays to hold elfsection indices, and indices into SYMTAB section
  55.    for the dwarf section names. The SYMTAB indices are used in generating
  56.    relocation records for dwarf sections. The relocation section numbers 
  57.    are held in reloc_sects[]
  58. */
  59. int elf_sects[NUM_DEBUG_SECTIONS];
  60. int sect_name_idx[NUM_DEBUG_SECTIONS];
  61. int reloc_sects[NUM_DEBUG_SECTIONS];
  62.  
  63. /*
  64.     Convert debug information to format so that 
  65.     it can be written on disk
  66. */
  67. Dwarf_Signed
  68. dwarf_transform_to_disk_form (
  69.     Dwarf_P_Debug     dbg,
  70.     Dwarf_Error     *error
  71. )
  72. {
  73.     /* 
  74.         Section data in written out in a number of 
  75.         buffers. Each _generate_*() function returns
  76.         a cumulative count of buffers for all the
  77.         sections. get_section_bytes() returns these
  78.         buffers one at a time 
  79.     */
  80.     int     nbufs;    
  81.  
  82.     /* Loop for all sections, and create section headers */
  83.     int     sect;    
  84.  
  85.         /* 
  86.         Index of section name into SYMTAB 
  87.             to be passed to call back routine 
  88.     */
  89.     int     name_idx;    
  90.  
  91.     int     err;    
  92.  
  93.     /* Create dwarf section headers */
  94.     for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) {
  95.         switch (sect) {
  96.  
  97.             case DEBUG_INFO : 
  98.                 if (dbg->de_dies == NULL) continue;
  99.                 break;
  100.  
  101.             case DEBUG_LINE :
  102.                 if (dbg->de_lines == NULL) continue;
  103.                 break;
  104.  
  105.             case DEBUG_ABBREV :
  106.                 if (dbg->de_dies == NULL) continue;
  107.                 break;
  108.  
  109.             case DEBUG_FRAME :
  110.                 if (dbg->de_frame_cies == NULL) continue;
  111.                 break;
  112.  
  113.             case DEBUG_ARANGES :
  114.                 if (dbg->de_arange == NULL) continue;
  115.                 break;
  116.  
  117.             case DEBUG_PUBNAMES :
  118.                 if (dbg->de_pubname == NULL) continue;
  119.         break;
  120.  
  121.         case DEBUG_STR :
  122.         if (dbg->de_strings == NULL) continue;
  123.         break;
  124.  
  125.         case DEBUG_FUNCNAMES :
  126.         if (dbg->de_funcname == NULL) continue;
  127.         break;
  128.  
  129.         case DEBUG_TYPENAMES :
  130.         if (dbg->de_typename == NULL) continue;
  131.         break;
  132.  
  133.         case DEBUG_VARNAMES :
  134.         if (dbg->de_varname == NULL) continue;
  135.         break;
  136.  
  137.         case DEBUG_WEAKNAMES :
  138.         if (dbg->de_weakname == NULL) continue;
  139.         break;
  140.     }
  141.  
  142.         elf_sects[sect] = dbg->de_func(sectnames[sect], IS_64BIT(dbg), 
  143.         SHT_MIPS_DWARF, (sect == DEBUG_FRAME ? SHF_MIPS_NOSTRIP : 0), 
  144.         SHN_UNDEF, 0, &name_idx, &err);
  145.     if (elf_sects[sect] == -1) {
  146.             DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT);
  147.     }
  148.         sect_name_idx[sect] = name_idx;
  149.     }
  150.  
  151.     nbufs = 0; 
  152.  
  153.     /* 
  154.         Changing the order in which the sections are generated 
  155.         may cause problems because of relocations. 
  156.     */
  157.  
  158.     if (dbg->de_lines) {
  159.     nbufs = _dwarf_pro_generate_debugline(dbg, error);
  160.     if (nbufs < 0) {
  161.         DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR, DW_DLV_NOCOUNT);
  162.     }
  163.     }
  164.  
  165.     if (dbg->de_frame_cies) {
  166.     nbufs = _dwarf_pro_generate_debugframe(dbg,error);
  167.     if (nbufs < 0) {
  168.         DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR, DW_DLV_NOCOUNT);
  169.     }
  170.     }
  171.  
  172.     if (dbg->de_dies) {
  173.     nbufs = _dwarf_pro_generate_debuginfo(dbg, error); 
  174.     if (nbufs < 0) {
  175.         DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, DW_DLV_NOCOUNT);
  176.     }
  177.     }
  178.  
  179.     if (dbg->de_arange) {
  180.     nbufs = _dwarf_transform_arange_to_disk(dbg, error);
  181.     if (nbufs < 0) {
  182.         DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, DW_DLV_NOCOUNT);
  183.     }
  184.     }
  185.  
  186.     if (dbg->de_pubname) {
  187.     nbufs = _dwarf_transform_pubname_to_disk(dbg, error);
  188.     if (nbufs < 0) {
  189.         DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, DW_DLV_NOCOUNT);
  190.     }
  191.     }
  192.  
  193.     if (dbg->de_funcname) {
  194.     nbufs = _dwarf_transform_funcname_to_disk(dbg, error);
  195.     if (nbufs < 0) {
  196.         DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, DW_DLV_NOCOUNT);
  197.     }
  198.     }
  199.  
  200.     if (dbg->de_typename) {
  201.     nbufs = _dwarf_transform_typename_to_disk(dbg, error);
  202.     if (nbufs < 0) {
  203.         DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, DW_DLV_NOCOUNT);
  204.     }
  205.     }
  206.  
  207.     if (dbg->de_varname) {
  208.     nbufs = _dwarf_transform_varname_to_disk(dbg, error);
  209.     if (nbufs < 0) {
  210.         DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, DW_DLV_NOCOUNT);
  211.     }
  212.     }
  213.  
  214.     if (dbg->de_weakname) {
  215.     nbufs = _dwarf_transform_weakname_to_disk(dbg, error);
  216.     if (nbufs < 0) {
  217.         DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, DW_DLV_NOCOUNT);
  218.     }
  219.     }
  220.  
  221.     return nbufs;
  222. }
  223.  
  224.  
  225. /*---------------------------------------------------------------
  226.     Generate debug_line section 
  227. ---------------------------------------------------------------*/
  228. int
  229. _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error *error)
  230. {
  231.     Dwarf_P_Inc_Dir curdir;
  232.     Dwarf_P_F_Entry curentry;
  233.     Dwarf_P_Line curline, prevline;
  234.     Dwarf_P_Section_Data cursect;
  235.             /* all data named cur* are used to loop thru 
  236.                linked lists */
  237.     Dwarf_P_Rel rel_head, rel_tail;
  238.             /* pointer to head & tail of list of relocation 
  239.                record */
  240.     int rel_nbytes;    /* number of bytes of relocation record */
  241.     int nstmts;
  242.     int sum_bytes;
  243.     int prolog_size;
  244.     int tot_size;
  245.     char *data;     /* holds disk form data */
  246.     int elfsectno;
  247.         int name_idx;    /* index of section name into SYMTAB */
  248.         int err;    /* to be passed to call back routine */
  249.     int i;
  250.     char *start_sec;        /* pointer to the buffer at 
  251.                        section start */
  252.     /* temps for memcpy */
  253.     Dwarf_Unsigned du;
  254.     Dwarf_Word dw;
  255.     Dwarf_Ubyte db;
  256.     Dwarf_Half dh;
  257.  
  258.     sum_bytes = 0;
  259.     rel_nbytes = 0;
  260.     rel_head = NULL;
  261.     rel_tail = NULL;
  262.  
  263.     elfsectno = elf_sects[DEBUG_LINE];
  264.  
  265.     /* statement prologue information */
  266.     prolog_size = 0;
  267.     /* include directories */
  268.     curdir = dbg->de_inc_dirs;
  269.     while (curdir) {
  270.         prolog_size += strlen(curdir->did_name)+1;
  271.         curdir = curdir->did_next;
  272.     }
  273.     prolog_size++;     /* last null following last directory entry. */
  274.  
  275.     /* file entries */
  276.     curentry = dbg->de_file_entries;
  277.     while (curentry) {
  278.         prolog_size += strlen(curentry->dfe_name)+1+curentry->dfe_nbytes;
  279.         curentry = curentry->dfe_next;
  280.     }
  281.     prolog_size++;    /* last null byte */
  282.  
  283.  
  284.     prolog_size +=    sizeof_uhalf(dbg) +     /* version # */
  285.             sizeof_uword(dbg) +     /* prologue length */
  286.             sizeof_ubyte(dbg) +    /* min_instr length */
  287.             sizeof_ubyte(dbg) +   /* default is_stmt */
  288.             sizeof_ubyte(dbg) +    /* linebase */
  289.             sizeof_ubyte(dbg) +    /* linerange */
  290.             sizeof_ubyte(dbg);    /* opcode base */
  291.  
  292.     /* length of table specifying # of opnds */
  293.     prolog_size += sizeof(std_opcode_len);
  294.     prolog_size += sizeof_uword(dbg) ;    /* for total length field */
  295.  
  296.     GET_NEW_CHUNK(dbg,elfsectno,data,prolog_size,error);
  297.     start_sec = data;
  298.  
  299.     /* copy over the data */
  300.     /* total_length */
  301.     if (IS_64BIT(dbg)) {
  302.        du = 0;            /* will be overwritten when total length is found */
  303.        memcpy((void *)data, (const void *)&du, sizeof(Dwarf_Unsigned));
  304.        data += sizeof(Dwarf_Unsigned);
  305.     } else {
  306.        dw = 0;            /* will be overwritten when total length is found */
  307.        memcpy((void *)data, (const void *)&dw, sizeof(Dwarf_Word));
  308.        data += sizeof(Dwarf_Word);
  309.     }
  310.  
  311.     dh = VERSION;
  312.     memcpy((void *)data,(const void *)&dh, sizeof(Dwarf_Half));
  313.     data += sizeof(Dwarf_Half);
  314.     /*prologue length */
  315.     du = prolog_size - (sizeof_uword(dbg)+sizeof(Dwarf_Half)+sizeof_uword(dbg));
  316.     if (IS_64BIT(dbg)) {
  317.         memcpy((void *)data,(const void *)&du, sizeof(Dwarf_Unsigned));
  318.         data += sizeof(Dwarf_Unsigned);
  319.     } else {
  320.         dw = du;
  321.         memcpy((void *)data,(const void *)&dw, sizeof(Dwarf_Word));
  322.         data += sizeof(Dwarf_Word);
  323.     }
  324.     db = MIN_INST_LENGTH;
  325.     memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  326.     data += sizeof(Dwarf_Ubyte);
  327.     db = DEFAULT_IS_STMT;
  328.     memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  329.     data += sizeof(Dwarf_Ubyte);
  330.     db = (Dwarf_Ubyte) LINE_BASE;
  331.     memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  332.     data += sizeof(Dwarf_Ubyte);
  333.     db = LINE_RANGE;
  334.     memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  335.     data += sizeof(Dwarf_Ubyte);
  336.     db = OPCODE_BASE;
  337.     memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  338.     data += sizeof(Dwarf_Ubyte);
  339.     memcpy((void *)data,(const void *)std_opcode_len, sizeof(std_opcode_len));
  340.     data += sizeof(std_opcode_len);
  341.  
  342.     /* copy over include directories */
  343.     curdir = dbg->de_inc_dirs;
  344.     while (curdir) {
  345.         strcpy(data,curdir->did_name);
  346.         data += strlen(curdir->did_name)+1;
  347.         curdir = curdir->did_next;
  348.     }
  349.     *data = '\0';    /* last null */
  350.     data++;
  351.  
  352.     /* copy file entries */
  353.     curentry = dbg->de_file_entries;
  354.     while (curentry) {
  355.         strcpy(data,curentry->dfe_name);
  356.         data += strlen(curentry->dfe_name)+1;
  357.         memcpy((void *)data,(const void *)curentry->dfe_args,curentry->dfe_nbytes);
  358.         data += curentry->dfe_nbytes;
  359.         curentry = curentry->dfe_next;
  360.     }
  361.     *data = '\0';
  362.     data++;
  363.  
  364.     sum_bytes += prolog_size;
  365.  
  366.     curline = dbg->de_lines;
  367.     prevline = (Dwarf_P_Line)
  368.         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
  369.     if (prevline == NULL) {
  370.         DWARF_P_DBG_ERROR(dbg,DW_DLE_LINE_ALLOC,-1);
  371.     }
  372.     _dwarf_pro_reg_init(prevline);
  373.     /* generate opcodes for line numbers */
  374.     while(curline) {
  375.       int nbytes;
  376.       char *arg;
  377.       int opc;
  378.       int no_lns_copy;    /* if lns copy opcode doesnt need to be 
  379.                    generated, if special opcode or 
  380.                    end sequence */
  381.       Dwarf_Unsigned addr_adv; 
  382.       int line_adv;
  383.  
  384.       no_lns_copy = 0;
  385.       if (curline->dpl_opc != 0) {
  386.         int inst_bytes;    /* no of bytes in extended opcode */
  387.         char *str;    /* hold leb encoded inst_bytes */
  388.         int str_nbytes;    /* no of bytes in str */
  389.         switch (curline->dpl_opc) {
  390.         case DW_LNE_end_sequence:
  391.  
  392.             /* Advance pc to end of text section. */
  393.                 addr_adv = curline->dpl_address - prevline->dpl_address;
  394.             if (addr_adv > 0) {
  395.                 db = DW_LNS_advance_pc;
  396.                 arg = _dwarf_pro_encode_leb128(
  397.                 addr_adv/MIN_INST_LENGTH, &nbytes);
  398.                 GET_CHUNK(dbg,elfsectno,data,
  399.                 nbytes+sizeof(Dwarf_Ubyte),error);
  400.                 memcpy((void *)data, (const void *)&db, 
  401.                 sizeof(Dwarf_Ubyte));
  402.                 data += sizeof(Dwarf_Ubyte);
  403.                 memcpy((void *)data,(const void *)arg, nbytes);
  404.                 data += nbytes + sizeof(Dwarf_Ubyte);
  405.                 sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
  406.                 prevline->dpl_address = curline->dpl_address;
  407.             }
  408.  
  409.             /*first null byte */
  410.             db = 0;
  411.             GET_CHUNK(dbg,elfsectno,data,sizeof(Dwarf_Ubyte),error);
  412.             memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  413.             data += sizeof(Dwarf_Ubyte);
  414.             sum_bytes += sizeof(Dwarf_Ubyte);
  415.  
  416.             /* write length of extended opcode */
  417.             inst_bytes = sizeof(Dwarf_Ubyte);
  418.             str = _dwarf_pro_encode_leb128(inst_bytes,&str_nbytes);
  419.             GET_CHUNK(dbg,elfsectno,data,str_nbytes,error);
  420.             memcpy((void *)data,(const void *)str,str_nbytes);
  421.             data += str_nbytes;
  422.             sum_bytes += str_nbytes;
  423.  
  424.             /* write extended opcode */
  425.             db = DW_LNE_end_sequence;
  426.             GET_CHUNK(dbg,elfsectno,data,sizeof(Dwarf_Ubyte),error);
  427.             memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  428.             data += sizeof(Dwarf_Ubyte);
  429.             sum_bytes += sizeof(Dwarf_Ubyte);
  430.             /* reset value to original values */
  431.             _dwarf_pro_reg_init(prevline);
  432.             no_lns_copy = 1;
  433.             /* this is set only for end_sequence, so that a 
  434.                dw_lns_copy is not generated */
  435.             break;
  436.  
  437.         case DW_LNE_set_address:
  438.  
  439.             /*first null byte */
  440.             db = 0;
  441.             GET_CHUNK(dbg,elfsectno,data,sizeof(Dwarf_Ubyte),error);
  442.             memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  443.             data += sizeof(Dwarf_Ubyte);
  444.             sum_bytes += sizeof(Dwarf_Ubyte);
  445.  
  446.             /* write length of extended opcode */
  447.             inst_bytes = sizeof(Dwarf_Ubyte)+sizeof_uword(dbg);
  448.             str = _dwarf_pro_encode_leb128(inst_bytes,&str_nbytes);
  449.             GET_CHUNK(dbg,elfsectno,data,str_nbytes,error);
  450.             memcpy((void *)data,(const void *)str,str_nbytes);
  451.             data += str_nbytes;
  452.             sum_bytes += str_nbytes;
  453.  
  454.             /* write extended opcode */
  455.             db = DW_LNE_set_address;
  456.             GET_CHUNK(dbg,elfsectno,data,sizeof_uword(dbg) + 
  457.                     sizeof(Dwarf_Ubyte),error);
  458.             memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  459.             data += sizeof(Dwarf_Ubyte);
  460.             sum_bytes += sizeof(Dwarf_Ubyte);
  461.  
  462.             /* store relocation record in linked list */
  463.             if (rel_head == NULL) {
  464.             rel_head = _dwarf_pro_get_new_relrec(dbg);
  465.             if (rel_head == NULL) {
  466.                 DWARF_P_DBG_ERROR(dbg,DW_DLE_REL_ALLOC, -1);
  467.             }
  468.             rel_tail = rel_head;
  469.             } else {
  470.             rel_tail->dr_next = _dwarf_pro_get_new_relrec(dbg);
  471.             if (rel_tail->dr_next == NULL) {
  472.                 DWARF_P_DBG_ERROR(dbg,DW_DLE_REL_ALLOC, -1);
  473.             }
  474.             rel_tail = rel_tail->dr_next;
  475.             rel_tail->dr_next = NULL;
  476.             }
  477.             rel_nbytes += _dwarf_pro_rel_info(dbg,rel_tail,sum_bytes,
  478.             curline->dpl_r_symidx,(IS_64BIT(dbg) ? R_MIPS_64 : R_MIPS_32));
  479.  
  480.             /* write offset */
  481.             if (IS_64BIT(dbg)) {
  482.             du = curline->dpl_address;
  483.                 memcpy((void *)data,(const void *)&du, sizeof(Dwarf_Unsigned));
  484.                 data += sizeof(Dwarf_Unsigned);
  485.                 sum_bytes += sizeof(Dwarf_Unsigned);
  486.             }
  487.             else {
  488.             dw = curline->dpl_address;
  489.                 memcpy((void *)data,(const void *)&dw, sizeof(Dwarf_Word));
  490.                 data += sizeof(Dwarf_Word);
  491.                 sum_bytes += sizeof(Dwarf_Word);
  492.             }
  493.             prevline->dpl_address = curline->dpl_address;
  494.             no_lns_copy = 1;
  495.             break;
  496.         }
  497.       } 
  498.       else {
  499.         if (curline->dpl_file != prevline->dpl_file) {
  500.         db = DW_LNS_set_file;
  501.         arg = _dwarf_pro_encode_leb128(curline->dpl_file,&nbytes);
  502.         GET_CHUNK(dbg,elfsectno,data,nbytes+sizeof(Dwarf_Ubyte),error);
  503.         memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  504.         data += sizeof(Dwarf_Ubyte);
  505.         memcpy((void *)data,(const void *)arg, nbytes);
  506.         data += nbytes;
  507.         sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
  508.         prevline->dpl_file = curline->dpl_file;
  509.         } 
  510.         if (curline->dpl_column != prevline->dpl_column) {
  511.         db = DW_LNS_set_column;
  512.         arg = _dwarf_pro_encode_leb128(curline->dpl_column,&nbytes);
  513.         GET_CHUNK(dbg,elfsectno,data,nbytes+sizeof(Dwarf_Ubyte),error);
  514.         memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  515.         data += sizeof(Dwarf_Ubyte);
  516.         memcpy((void *)data,(const void *)arg, nbytes);
  517.         data += nbytes;
  518.         sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
  519.         prevline->dpl_column = curline->dpl_column;
  520.         }
  521.         if (curline->dpl_is_stmt != prevline->dpl_is_stmt) {
  522.         db = DW_LNS_negate_stmt;
  523.         GET_CHUNK(dbg,elfsectno,data,sizeof(Dwarf_Ubyte),error);
  524.         memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  525.         data += sizeof(Dwarf_Ubyte);
  526.         sum_bytes += sizeof(Dwarf_Ubyte);
  527.         prevline->dpl_is_stmt = curline->dpl_is_stmt;
  528.         }
  529.         if (curline->dpl_basic_block == true && prevline->dpl_basic_block == false) {
  530.         db = DW_LNS_set_basic_block;
  531.         GET_CHUNK(dbg,elfsectno,data,sizeof(Dwarf_Ubyte),error);
  532.         memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  533.         data += sizeof(Dwarf_Ubyte);
  534.         sum_bytes += sizeof(Dwarf_Ubyte);
  535.         prevline->dpl_basic_block = curline->dpl_basic_block;
  536.         }
  537.         addr_adv = curline->dpl_address - prevline->dpl_address;
  538.         line_adv = curline->dpl_line - prevline->dpl_line;
  539.         if ((addr_adv % MIN_INST_LENGTH) != 0) {
  540.         DWARF_P_DBG_ERROR(dbg,DW_DLE_WRONG_ADDRESS,-1);
  541.         }
  542.         if ((opc = _dwarf_pro_get_opc(addr_adv,line_adv)) > 0) {
  543.         no_lns_copy = 1;
  544.         db = opc;
  545.             GET_CHUNK(dbg,elfsectno,data,sizeof(Dwarf_Ubyte),error);
  546.             memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  547.             data += sizeof(Dwarf_Ubyte);
  548.             sum_bytes += sizeof(Dwarf_Ubyte);
  549.         prevline->dpl_basic_block = false;
  550.         prevline->dpl_address = curline->dpl_address;
  551.         prevline->dpl_line = curline->dpl_line;
  552.         }
  553.         else {
  554.         if (addr_adv > 0) {
  555.             db = DW_LNS_advance_pc;
  556.             arg = _dwarf_pro_encode_leb128(addr_adv/MIN_INST_LENGTH, &nbytes);
  557.             GET_CHUNK(dbg,elfsectno,data,nbytes+sizeof(Dwarf_Ubyte),error);
  558.             memcpy((void *)data, (const void *)&db, sizeof(Dwarf_Ubyte));
  559.             data += sizeof(Dwarf_Ubyte);
  560.             memcpy((void *)data,(const void *)arg, nbytes);
  561.             data += nbytes + sizeof(Dwarf_Ubyte);
  562.             sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
  563.             prevline->dpl_basic_block = false;
  564.             prevline->dpl_address = curline->dpl_address;
  565.         }
  566.         if (line_adv != 0) {
  567.             db = DW_LNS_advance_line;
  568.             arg = _dwarf_pro_encode_signed_leb128(line_adv, &nbytes);
  569.             GET_CHUNK(dbg,elfsectno,data,nbytes+sizeof(Dwarf_Ubyte),error);
  570.             memcpy((void *)data, (const void *)&db, sizeof(Dwarf_Ubyte));
  571.             data += sizeof(Dwarf_Ubyte);
  572.             memcpy((void *)data,(const void *)arg, nbytes);
  573.             data += nbytes + sizeof(Dwarf_Ubyte);
  574.             sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
  575.             prevline->dpl_basic_block = false;
  576.             prevline->dpl_line = curline->dpl_line;
  577.         }
  578.         }
  579.       }        /* ends else for opc != 0 */
  580.       if (no_lns_copy == 0) {    /* if not a special or dw_lne_end_seq
  581.                         generate a matrix line */
  582.         db = DW_LNS_copy;
  583.             GET_CHUNK(dbg,elfsectno,data,sizeof(Dwarf_Ubyte),error);
  584.             memcpy((void *)data,(const void *)&db, sizeof(Dwarf_Ubyte));
  585.             data += sizeof(Dwarf_Ubyte);
  586.             sum_bytes += sizeof(Dwarf_Ubyte);
  587.         prevline->dpl_basic_block = false;
  588.       }
  589.       curline = curline->dpl_next;
  590.     }
  591.  
  592.     /* write total length field */
  593.     du = sum_bytes - sizeof_uword(dbg);    /* subtract length field */
  594.     if (IS_64BIT(dbg))
  595.         memcpy((void *)start_sec, (const void *)&du, sizeof(Dwarf_Unsigned));
  596.     else {
  597.         dw = du;
  598.         memcpy((void *)start_sec, (const void *)&dw, sizeof(Dwarf_Word));
  599.     }
  600.  
  601.         if (rel_nbytes > 0) {
  602.             reloc_sects[DEBUG_LINE] = dbg->de_func(".rel.debug_line",
  603.             IS_64BIT(dbg), SHT_REL, 0, SHN_UNDEF,elf_sects[DEBUG_LINE], 
  604.         &name_idx, &err);
  605.             if (reloc_sects[DEBUG_LINE] == -1) {
  606.                 DWARF_P_DBG_ERROR(dbg,DW_DLE_ELF_SECT_ERR,DW_DLV_NOCOUNT);
  607.             }
  608.  
  609.             /* write out relocation records */
  610.             elfsectno = reloc_sects[DEBUG_LINE];
  611.             i = _dwarf_pro_write_reloc_section(dbg,rel_head,elfsectno,rel_nbytes,error);
  612.             if (i < 0) return i;
  613.         }
  614.  
  615.     return dbg->de_n_debug_sect;
  616. }
  617.  
  618. /*---------------------------------------------------------------
  619.     Generate debug_frame section 
  620. ---------------------------------------------------------------*/
  621. int 
  622. _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error *error)
  623. {
  624.     int elfsectno;
  625.     int i;
  626.     int firsttime, pad;    /* pad for padding to align cies and fdes */
  627.     Dwarf_P_Cie curcie;
  628.     Dwarf_P_Fde curfde;
  629.     char *data;
  630.     Dwarf_Word dw;
  631.     Dwarf_Unsigned du;
  632.     Dwarf_Ubyte db;
  633.     long *cie_offs;        /* holds byte offsets for links to fde's */
  634.     long cie_length;
  635.     int cie_no;
  636.     Dwarf_P_Rel rel_head, rel_tail;    /* relocation pointers */
  637.     int rel_nbytes;            /* bytes in relocation section */
  638.     int name_idx;            /* holds index for rel section */
  639.     int err;
  640.     Dwarf_Unsigned cur_off;        /* current offset of written 
  641.                        data, held for relocation info */
  642.  
  643.     elfsectno = elf_sects[DEBUG_FRAME];
  644.  
  645.     curcie = dbg->de_frame_cies;
  646.     cie_length = 0;
  647.     rel_head = NULL;
  648.     rel_tail = NULL;
  649.     rel_nbytes = 0;
  650.     cur_off = 0;
  651.     cie_offs = (long *)
  652.         _dwarf_p_get_alloc(dbg, sizeof(long)*dbg->de_n_cie);
  653.     if (cie_offs == NULL) {
  654.         DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_OFFS_ALLOC,-1);
  655.     }
  656.     firsttime = 1;
  657.     /* generate cie number as we go along */
  658.     cie_no = 1;
  659.     while (curcie) {
  660.         char *code_al;
  661.         int c_bytes;
  662.         char *data_al;
  663.         int d_bytes;
  664.  
  665.         code_al = _dwarf_pro_encode_leb128(curcie->cie_code_align, &c_bytes);
  666.         data_al = _dwarf_pro_encode_leb128(curcie->cie_data_align, &d_bytes);
  667.  
  668.         /* get the correct offset */
  669.         if (firsttime)
  670.         cie_offs[cie_no-1] = 0;
  671.         else
  672.         cie_offs[cie_no-1] = cie_offs[cie_no-2]+cie_length+sizeof_uword(dbg);
  673.         cie_no++;    
  674.         cie_length = sizeof(Dwarf_Unsigned) +     /* cie_id */
  675.              sizeof(Dwarf_Ubyte) +        /* cie version */
  676.              strlen(curcie->cie_aug)+1  +     /* augmentation */
  677.              c_bytes +
  678.              d_bytes +
  679.              sizeof(Dwarf_Ubyte) +        /* return reg address */
  680.              curcie->cie_inst_bytes;
  681.         pad = PADDING(cie_length, sizeof_uword(dbg));
  682.         cie_length += pad;
  683.         if (firsttime) {
  684.         GET_NEW_CHUNK(dbg,elfsectno,data,cie_length+sizeof_uword(dbg), error);
  685.         firsttime = 0;
  686.         }
  687.         else
  688.         GET_CHUNK(dbg,elfsectno,data,cie_length+sizeof_uword(dbg), error);
  689.         du = cie_length;
  690.         if (IS_64BIT(dbg)) {
  691.         memcpy((void *)data, (const void *)&du, sizeof(Dwarf_Unsigned));
  692.         data += sizeof(Dwarf_Unsigned);
  693.         du = DW_CIE_ID;
  694.         memcpy((void *)data, (const void *)&du, sizeof(Dwarf_Unsigned));
  695.         data += sizeof(Dwarf_Unsigned);
  696.         }
  697.         else {
  698.         dw = du;
  699.         memcpy((void *)data, (const void *)&dw, sizeof(Dwarf_Word));
  700.         data += sizeof(Dwarf_Word);
  701.         dw = DW_CIE_ID;
  702.         memcpy((void *)data, (const void *)&dw, sizeof(Dwarf_Word));
  703.         data += sizeof(Dwarf_Word);
  704.         }
  705.         db = curcie->cie_version;
  706.         memcpy((void *)data, (const void *)&db, sizeof(Dwarf_Ubyte));
  707.         data += sizeof(Dwarf_Ubyte);
  708.         strcpy(data, curcie->cie_aug);
  709.         data += strlen(curcie->cie_aug)+1;
  710.         memcpy((void *)data, (const void *)code_al, c_bytes);
  711.         data += c_bytes;
  712.         memcpy((void *)data, (const void *)data_al, d_bytes);
  713.         data += d_bytes;
  714.         db = curcie->cie_ret_reg;
  715.         memcpy((void *)data, (const void *)&db, sizeof(Dwarf_Ubyte));
  716.         data += sizeof(Dwarf_Ubyte);
  717.         memcpy((void *)data, (const void *)curcie->cie_inst, curcie->cie_inst_bytes);
  718.         data += curcie->cie_inst_bytes;
  719.         for (i = 0 ; i < pad ; i++) {
  720.         *data = DW_CFA_nop;
  721.         data++;
  722.         }
  723.         curcie = curcie->cie_next;
  724.     }
  725.     /* calculate current offset */
  726.     cur_off = cie_offs[cie_no-2] + cie_length + sizeof_uword(dbg);
  727.  
  728.     /* write out fde's */
  729.     curfde = dbg->de_frame_fdes;
  730.     while (curfde) {
  731.         Dwarf_P_Frame_Pgm curinst;
  732.         long fde_length;
  733.         int pad;
  734.  
  735.         fde_length = curfde->fde_n_bytes + 
  736.              sizeof_uword(dbg) +        /* cie pointer */
  737.              sizeof_uword(dbg) +         /* initial loc */
  738.              sizeof_uword(dbg);        /* address range */
  739.  
  740.         /* using fde offset, generate DW_AT_MIPS_fde attribute 
  741.            for the die corresponding to this fde */
  742.         if (_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, error) < 0)
  743.         return -1;
  744.  
  745.         /* store relocation for cie pointer */
  746.         if (rel_head == NULL) {
  747.         rel_head = _dwarf_pro_get_new_relrec(dbg);
  748.         if (rel_head == NULL) {
  749.             DWARF_P_DBG_ERROR(dbg,DW_DLE_REL_ALLOC, -1);
  750.         }
  751.         rel_tail = rel_head;
  752.         } else {
  753.         rel_tail->dr_next = _dwarf_pro_get_new_relrec(dbg);
  754.         if (rel_tail->dr_next == NULL) {
  755.             DWARF_P_DBG_ERROR(dbg,DW_DLE_REL_ALLOC, -1);
  756.         }
  757.         rel_tail = rel_tail->dr_next;
  758.         rel_tail->dr_next = NULL;
  759.         }
  760.         rel_nbytes += _dwarf_pro_rel_info(
  761.                 dbg,
  762.                 rel_tail,
  763.                 /*  + for length field */
  764.                 cur_off+sizeof_uword(dbg),
  765.                 sect_name_idx[DEBUG_FRAME],
  766.                 (IS_64BIT(dbg) ? R_MIPS_64:R_MIPS_32));
  767.  
  768.         /* store relocation information for initial location */
  769.         rel_tail->dr_next = _dwarf_pro_get_new_relrec(dbg);
  770.         if (rel_tail->dr_next == NULL) {
  771.          DWARF_P_DBG_ERROR(dbg,DW_DLE_REL_ALLOC, -1);
  772.         }
  773.         rel_tail = rel_tail->dr_next;
  774.         rel_tail->dr_next = NULL;
  775.         rel_nbytes += _dwarf_pro_rel_info(
  776.                 dbg,
  777.                 rel_tail,
  778.                 /* 2* for length and cie_ptr fields */
  779.                 cur_off+2*sizeof_uword(dbg),
  780.                 curfde->fde_r_symidx,
  781.                 (IS_64BIT(dbg) ? R_MIPS_64:R_MIPS_32));
  782.  
  783.         /* adjust for padding */
  784.         pad = PADDING(fde_length, sizeof_uword(dbg));
  785.         fde_length += pad;
  786.  
  787.         cur_off += fde_length + sizeof_uword(dbg);
  788.  
  789.         /* write out fde */
  790.         GET_CHUNK(dbg,elfsectno,data,fde_length+sizeof_uword(dbg), error);
  791.         du = fde_length;
  792.         if (IS_64BIT(dbg)) {
  793.         memcpy((void *)data, (const void *)&du, sizeof(Dwarf_Unsigned));
  794.         data += sizeof(Dwarf_Unsigned);
  795.             du = cie_offs[curfde->fde_cie-1];
  796.         memcpy((void *)data, (const void *)&du, sizeof(Dwarf_Unsigned));
  797.         data += sizeof(Dwarf_Unsigned);
  798.         du = curfde->fde_initloc;
  799.         memcpy((void *)data, (const void *)&du, sizeof(Dwarf_Unsigned));
  800.         data += sizeof(Dwarf_Unsigned);
  801.         du = curfde->fde_addr_range;
  802.         memcpy((void *)data, (const void *)&du, sizeof(Dwarf_Unsigned));
  803.         data += sizeof(Dwarf_Unsigned);
  804.         } 
  805.         else {
  806.         dw = du;
  807.         memcpy((void *)data, (const void *)&dw, sizeof(Dwarf_Word));
  808.         data += sizeof(Dwarf_Word);
  809.         dw = cie_offs[curfde->fde_cie-1];
  810.         memcpy((void *)data, (const void *)&dw, sizeof(Dwarf_Word));
  811.         data += sizeof(Dwarf_Word);
  812.         dw = curfde->fde_initloc;
  813.         memcpy((void *)data, (const void *)&dw, sizeof(Dwarf_Word));
  814.         data += sizeof(Dwarf_Word);
  815.         dw = curfde->fde_addr_range;
  816.         memcpy((void *)data, (const void *)&dw, sizeof(Dwarf_Word));
  817.         data += sizeof(Dwarf_Word);
  818.         }
  819.  
  820.         curinst = curfde->fde_inst;
  821.         while (curinst) {
  822.         db = curinst->dfp_opcode;
  823.         memcpy((void *)data, (const void *)&db, sizeof(Dwarf_Ubyte));
  824.         data += sizeof(Dwarf_Ubyte);
  825.         memcpy((void *)data, (const void *)curinst->dfp_args,curinst->dfp_nbytes);
  826.         data += curinst->dfp_nbytes;
  827.         curinst = curinst->dfp_next;
  828.         }
  829.         /* padding */
  830.         for (i = 0 ; i < pad ; i++) {
  831.         *data = DW_CFA_nop;
  832.         data++;
  833.         }
  834.     curfde = curfde->fde_next;
  835.     }
  836.  
  837.         if (rel_nbytes > 0) {
  838.             reloc_sects[DEBUG_FRAME] = dbg->de_func(".rel.debug_frame",
  839.         IS_64BIT(dbg), SHT_REL, 0, SHN_UNDEF, elf_sects[DEBUG_FRAME], 
  840.         &name_idx, &err);
  841.             if (reloc_sects[DEBUG_FRAME] == -1) {
  842.                 DWARF_P_DBG_ERROR(dbg,DW_DLE_ELF_SECT_ERR,DW_DLV_NOCOUNT);
  843.             }
  844.  
  845.             /* write out relocation records */
  846.             elfsectno = reloc_sects[DEBUG_FRAME];
  847.             i = _dwarf_pro_write_reloc_section(dbg,rel_head,elfsectno,rel_nbytes,error);
  848.             if (i < 0) return i;
  849.         }
  850.  
  851.     return dbg->de_n_debug_sect;
  852. }
  853.  
  854.  
  855. /*---------------------------------------------------------------
  856.     Generate debug_info and debug_abbrev sections
  857. ---------------------------------------------------------------*/
  858. int
  859. _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,Dwarf_Error *error)
  860. {
  861.     int elfsectno;
  862.     char *data;
  863.     int cu_header_size;
  864.     Dwarf_P_Abbrev curabbrev, abbrev_head, abbrev_tail;
  865.     Dwarf_P_Die curdie;
  866.     Dwarf_P_Die first_child;
  867.     Dwarf_Word dw;
  868.     Dwarf_Unsigned du;
  869.     Dwarf_Half dh;
  870.     Dwarf_Ubyte db;
  871.     Dwarf_Half version;            /* need 2 byte quantity */
  872.     Dwarf_Unsigned die_off;            /* offset of die in debug_info */
  873.     int n_abbrevs;
  874.  
  875.         int name_idx;    /* index of section name into SYMTAB */
  876.         int err;    /* to be passed to call back routine */
  877.     int firsttime;
  878.     char *start_sec;
  879.     Dwarf_P_Rel rel_head, rel_tail;    /* linked list of relocation records */
  880.     int rel_nbytes;            /* number of bytes of relocation info */
  881.     int retval;        /* return value from functions called */
  882.  
  883.     abbrev_head = abbrev_tail = NULL;
  884.     rel_head = rel_tail = NULL;
  885.     rel_nbytes = 0;
  886.     elfsectno = elf_sects[DEBUG_INFO];
  887.     
  888.     /* write cu header */
  889.     cu_header_size = sizeof_uword(dbg) +        /* length of info section */
  890.              sizeof(Dwarf_Half) +        /* version stamp */
  891.              sizeof_uword(dbg) +        /* offset into abbrev table */
  892.              sizeof(Dwarf_Ubyte);        /* size of target address */
  893.     GET_NEW_CHUNK(dbg,elfsectno,data,cu_header_size,error);
  894.     start_sec = data;
  895.     if (IS_64BIT(dbg)) {
  896.         du = 0;        /* debug info size, now zero */
  897.         memcpy((void *)data, (const void *)&du, sizeof(Dwarf_Unsigned));
  898.         data += sizeof(Dwarf_Unsigned);
  899.     }
  900.     else {
  901.         dw = 0;
  902.         memcpy((void *)data, (const void *)&dw, sizeof(Dwarf_Word));
  903.         data += sizeof(Dwarf_Word);
  904.     }
  905.     version = CURRENT_VERSION_STAMP;    /* assume this length will not change */
  906.     memcpy((void *)data,(const void *)&version,sizeof(Dwarf_Half));
  907.     data += sizeof(Dwarf_Half);
  908.     if (IS_64BIT(dbg)) {
  909.         du = 0;        /* offset into abbrev table */
  910.         memcpy((void *)data, (const void *)&du, sizeof(Dwarf_Unsigned));
  911.         data += sizeof(Dwarf_Unsigned);
  912.     }
  913.     else {
  914.         dw = 0;
  915.         memcpy((void *)data, (const void *)&dw, sizeof(Dwarf_Word));
  916.         data += sizeof(Dwarf_Word);
  917.     }
  918.     if (IS_64BIT(dbg))
  919.         db = sizeof(Dwarf_Addr);
  920.     else
  921.         db = sizeof(Dwarf_Word);
  922.     memcpy((void *)data, (const void *)&db,1);
  923.     data++;
  924.  
  925.     curdie = dbg->de_dies;
  926.  
  927.     /* create AT_stmt_list attribute if necessary */
  928.     if (dbg->de_lines != NULL) 
  929.         if (_dwarf_pro_add_AT_stmt_list(dbg,curdie,error) < 0)
  930.         return -1;
  931.  
  932.     die_off = cu_header_size;
  933.  
  934.     /* 
  935.         Relocation for abbrev offset in cu header
  936.             store relocation record in linked list 
  937.     */
  938.     rel_head = rel_tail = _dwarf_pro_get_new_relrec(dbg);
  939.     if (rel_head == NULL) {
  940.         DWARF_P_DBG_ERROR(dbg,DW_DLE_REL_ALLOC, -1);
  941.     }
  942.     rel_nbytes += _dwarf_pro_rel_info(dbg, rel_tail,
  943.         SIZEOF_UWORD(dbg)+sizeof(Dwarf_Half), sect_name_idx[DEBUG_ABBREV],
  944.         IS_64BIT(dbg)?R_MIPS_64:R_MIPS_32);
  945.  
  946.     /* pass 0: only top level dies, add at_sibling attribute to 
  947.            those dies with children */
  948.     first_child = curdie->di_child;
  949.     while (first_child && first_child->di_right) {
  950.         if (first_child->di_child)
  951.             dwarf_add_AT_reference(dbg,
  952.                        first_child, 
  953.                        DW_AT_sibling,
  954.                        first_child->di_right,
  955.                        error);
  956.         first_child = first_child->di_right;
  957.     }
  958.  
  959.     /* pass 1: create abbrev info, get die offsets, calc relocations */
  960.     while (curdie != NULL) {
  961.         char *abb_idx;    /* in leb128 reps */
  962.         int nbytes;
  963.         Dwarf_P_Attribute curattr;
  964.  
  965.         curdie->di_offset = die_off;
  966.         curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head);
  967.         if (curabbrev == NULL) {
  968.         DWARF_P_DBG_ERROR(dbg,DW_DLE_ABBREV_ALLOC, -1);
  969.         }
  970.         if (abbrev_head == NULL) {
  971.         n_abbrevs = 1;
  972.         curabbrev->abb_idx = n_abbrevs;
  973.         abbrev_tail = abbrev_head = curabbrev;
  974.         } else {
  975.         /* check if its a new abbreviation, if yes, add to tail */
  976.         if (curabbrev->abb_idx == 0) {
  977.             n_abbrevs++;
  978.             curabbrev->abb_idx = n_abbrevs;
  979.             abbrev_tail->abb_next = curabbrev;
  980.             abbrev_tail = curabbrev;
  981.         }
  982.         }
  983.         curdie->di_abbrev = _dwarf_pro_encode_leb128(curabbrev->abb_idx,&nbytes);
  984.         curdie->di_abbrev_nbytes = nbytes;
  985.         die_off += nbytes;
  986.         curattr = curdie->di_attrs;
  987.         while (curattr) {
  988.         if (curattr->ar_rel_type != R_MIPS_NONE) {
  989.             /* store relocation record in linked list */
  990.             if (rel_head == NULL) {
  991.             rel_head = _dwarf_pro_get_new_relrec(dbg);
  992.             if (rel_head == NULL) {
  993.                 DWARF_P_DBG_ERROR(dbg,DW_DLE_REL_ALLOC, -1);
  994.             }
  995.             rel_tail = rel_head;
  996.             } else {
  997.             rel_tail->dr_next = _dwarf_pro_get_new_relrec(dbg);
  998.             if (rel_tail->dr_next == NULL) {
  999.                 DWARF_P_DBG_ERROR(dbg,DW_DLE_REL_ALLOC, -1);
  1000.             }
  1001.             rel_tail = rel_tail->dr_next;
  1002.             rel_tail->dr_next = NULL;
  1003.             }
  1004.             switch (curattr->ar_attribute) {
  1005.             case DW_AT_stmt_list:
  1006.                 curattr->ar_rel_symidx = sect_name_idx[DEBUG_LINE];
  1007.                 break;
  1008.             case DW_AT_MIPS_fde:
  1009.                 curattr->ar_rel_symidx = sect_name_idx[DEBUG_FRAME];
  1010.                 break;
  1011.             default:
  1012.                 break;
  1013.             }
  1014.             rel_nbytes += _dwarf_pro_rel_info(dbg,rel_tail,
  1015.             die_off+curattr->ar_rel_offset,curattr->ar_rel_symidx,
  1016.             curattr->ar_rel_type);
  1017.         }
  1018.         die_off += curattr->ar_nbytes;
  1019.         curattr = curattr->ar_next;
  1020.         }
  1021.         /* depth first search */
  1022.         if (curdie->di_child)
  1023.         curdie = curdie->di_child;
  1024.         else {
  1025.         while (curdie != NULL && curdie->di_right == NULL) {
  1026.             curdie = curdie->di_parent;
  1027.             die_off++; /* since we are writing a null die at the 
  1028.                   end of each sibling chain */
  1029.         }
  1030.         if (curdie != NULL) 
  1031.             curdie = curdie->di_right;
  1032.         }
  1033.     }
  1034.  
  1035.     /* pass 2: Write out the die information */
  1036.     curdie = dbg->de_dies;
  1037.     while (curdie != NULL) {
  1038.         Dwarf_P_Attribute curattr;
  1039.  
  1040.         /* index to abbreviation table */
  1041.         GET_CHUNK(dbg,elfsectno,data,curdie->di_abbrev_nbytes,error);
  1042.         memcpy((void *)data, (const void *)curdie->di_abbrev,curdie->di_abbrev_nbytes);
  1043.  
  1044.         /* Attribute values - need to fill in all form attributes */
  1045.         curattr = curdie->di_attrs;
  1046.         while (curattr) {
  1047.         GET_CHUNK(dbg,elfsectno,data,curattr->ar_nbytes,error);
  1048.         switch (curattr->ar_attribute_form) {
  1049.             case DW_FORM_ref1:
  1050.             { if (curattr->ar_ref_die->di_offset > (unsigned) 0xff) {
  1051.                    DWARF_P_DBG_ERROR(dbg,DW_DLE_OFFSET_UFLW,-1);
  1052.                  }
  1053.                  db = curattr->ar_ref_die->di_offset;
  1054.                  memcpy((void *)data,(const void *)&db,sizeof(Dwarf_Ubyte));
  1055.                  data += sizeof(Dwarf_Ubyte);
  1056.                  break;
  1057.             }
  1058.             case DW_FORM_ref2:
  1059.             { if (curattr->ar_ref_die->di_offset > (unsigned) 0xffff) {
  1060.                    DWARF_P_DBG_ERROR(dbg,DW_DLE_OFFSET_UFLW,-1);
  1061.                  }
  1062.                  dh = curattr->ar_ref_die->di_offset;
  1063.                  memcpy((void *)data,(const void *)&dh,sizeof(Dwarf_Half));
  1064.                  data += sizeof(Dwarf_Half);
  1065.                  break;
  1066.             }
  1067.             case DW_FORM_ref_addr:
  1068.             case DW_FORM_ref4:
  1069.             { if (curattr->ar_ref_die->di_offset > (unsigned) 0xffffffff) {
  1070.                    DWARF_P_DBG_ERROR(dbg,DW_DLE_OFFSET_UFLW,-1);
  1071.                  }
  1072.                  dw = curattr->ar_ref_die->di_offset;
  1073.                  memcpy((void *)data,(const void *)&dw,sizeof(Dwarf_Word));
  1074.                  data += sizeof(Dwarf_Word);
  1075.                  break;
  1076.             }
  1077.             case DW_FORM_ref8:
  1078.             case DW_FORM_ref_udata:
  1079.              du = curattr->ar_ref_die->di_offset;
  1080.              memcpy((void *)data,(const void *)&du,sizeof(Dwarf_Unsigned));
  1081.              data += sizeof(Dwarf_Unsigned);
  1082.              break;
  1083.             default:
  1084.               memcpy((void *)data,(const void *)curattr->ar_data,curattr->ar_nbytes);
  1085.               break;
  1086.         }
  1087.         curattr = curattr->ar_next;
  1088.         }
  1089.  
  1090.         /* depth first search */
  1091.         if (curdie->di_child)
  1092.         curdie = curdie->di_child;
  1093.         else {
  1094.         while (curdie != NULL && curdie->di_right == NULL) {
  1095.             GET_CHUNK(dbg,elfsectno,data,1,error);
  1096.             *data = '\0';
  1097.             data++;
  1098.             curdie = curdie->di_parent;
  1099.         }
  1100.         if (curdie != NULL) 
  1101.             curdie = curdie->di_right;
  1102.         }
  1103.     }
  1104.  
  1105.     /* write out debug_info size */
  1106.     if (IS_64BIT(dbg)) {
  1107.         du = die_off - sizeof(Dwarf_Unsigned); /* dont include length field */
  1108.         memcpy((void *)start_sec, (const void *)&du, sizeof(Dwarf_Unsigned));
  1109.     } else {
  1110.         dw = die_off - sizeof(Dwarf_Word);    /* dont include length field */
  1111.         memcpy((void *)start_sec, (const void *)&dw, sizeof(Dwarf_Word));
  1112.     }
  1113.  
  1114.  
  1115.     /* write out debug_abbrev section */
  1116.     elfsectno = elf_sects[DEBUG_ABBREV];
  1117.  
  1118.     firsttime = 1;
  1119.     curabbrev = abbrev_head;
  1120.     while (curabbrev) {
  1121.         char *val;
  1122.         int nbytes;
  1123.         int idx;
  1124.  
  1125.         val = _dwarf_pro_encode_leb128(curabbrev->abb_idx,&nbytes);
  1126.         if (firsttime) {
  1127.         GET_NEW_CHUNK(dbg,elfsectno,data,nbytes,error);
  1128.         firsttime = 0;
  1129.         }
  1130.         else
  1131.         GET_CHUNK(dbg,elfsectno,data,nbytes,error);
  1132.         memcpy((void *)data,(const void *)val, nbytes);
  1133.         val = _dwarf_pro_encode_leb128(curabbrev->abb_tag,&nbytes);
  1134.         GET_CHUNK(dbg,elfsectno,data,nbytes,error);
  1135.         memcpy((void *)data,(const void *)val, nbytes);
  1136.         db = curabbrev->abb_children;
  1137.         GET_CHUNK(dbg,elfsectno,data,sizeof(Dwarf_Ubyte),error);
  1138.         memcpy((void *)data,(const void *)&db,sizeof(Dwarf_Ubyte));
  1139.     
  1140.         /* add attributes and forms */
  1141.         for (idx = 0; idx < curabbrev->abb_n_attr; idx++) {
  1142.         val = _dwarf_pro_encode_leb128(curabbrev->abb_attrs[idx],&nbytes);
  1143.         GET_CHUNK(dbg,elfsectno,data,nbytes,error);
  1144.         memcpy((void *)data,(const void *)val, nbytes);
  1145.         val = _dwarf_pro_encode_leb128(curabbrev->abb_forms[idx],&nbytes);
  1146.         GET_CHUNK(dbg,elfsectno,data,nbytes,error);
  1147.         memcpy((void *)data,(const void *)val, nbytes);
  1148.         }
  1149.         GET_CHUNK(dbg,elfsectno,data,2,error);    /* two zeros, for last entry */
  1150.         *data = 0;
  1151.         data++;
  1152.         *data = 0;
  1153.  
  1154.         curabbrev = curabbrev->abb_next;
  1155.     }
  1156.  
  1157.     if (rel_nbytes > 0) {
  1158.             reloc_sects[DEBUG_INFO] = dbg->de_func(".rel.debug_info",
  1159.         IS_64BIT(dbg), SHT_REL, 0, SHN_UNDEF,elf_sects[DEBUG_INFO], 
  1160.         &name_idx, &err);
  1161.             if (reloc_sects[DEBUG_INFO] == -1) {
  1162.                 DWARF_P_DBG_ERROR(dbg,DW_DLE_ELF_SECT_ERR,DW_DLV_NOCOUNT);
  1163.         }
  1164.         /* write out relocation records */
  1165.         elfsectno = reloc_sects[DEBUG_INFO];
  1166.         retval = _dwarf_pro_write_reloc_section(dbg,rel_head,
  1167.             elfsectno,rel_nbytes,error);
  1168.         if (retval < 0) return retval;
  1169.     }
  1170.  
  1171.     return dbg->de_n_debug_sect;
  1172. }
  1173.  
  1174.  
  1175. /*---------------------------------------------------------------------
  1176.     Get a buffer of section data, section_idx is unused. length 
  1177.     shows length of returned data 
  1178. ----------------------------------------------------------------------*/
  1179. Dwarf_Ptr
  1180. dwarf_get_section_bytes(
  1181.     Dwarf_P_Debug dbg,
  1182.     Dwarf_Signed dwarf_section,
  1183.     Dwarf_Signed *section_idx, 
  1184.     Dwarf_Unsigned *length,
  1185.     Dwarf_Error *error)
  1186. {
  1187.     Dwarf_Ptr buf;
  1188.     Dwarf_P_Section_Data need_to_free;
  1189.     *section_idx = dbg->de_debug_sects->ds_elf_sect_no;
  1190.     *length = dbg->de_debug_sects->ds_nbytes;
  1191.     buf = (Dwarf_Ptr *)dbg->de_debug_sects->ds_data;
  1192.     need_to_free = dbg->de_debug_sects;
  1193.     dbg->de_debug_sects = dbg->de_debug_sects->ds_next;
  1194.     dbg->de_n_debug_sect--;
  1195.     /* leave need_to_free as is right now */
  1196.  
  1197.     return buf;
  1198. }
  1199.  
  1200. /*
  1201.     Storage handler. Gets either a new chunk of memory, or
  1202.     a pointer in existing memory, from the linked list attached
  1203.     to dbg at de_debug_sects, depending on size of nbytes
  1204.  
  1205.     Assume dbg not null, checked in top level routine 
  1206. */
  1207. char *
  1208. _dwarf_pro_buffer (
  1209.     Dwarf_P_Debug     dbg,
  1210.     int         elfsectno,
  1211.     int         nbytes,
  1212.     int         new_chunk
  1213. )
  1214. {
  1215.     Dwarf_P_Section_Data     cursect;
  1216.  
  1217.     cursect = dbg->de_last_debug_sect;
  1218.     if (new_chunk || cursect == NULL || 
  1219.     cursect->ds_nbytes + nbytes > CHUNK_SIZE) {
  1220.  
  1221.     cursect = (Dwarf_P_Section_Data)
  1222.         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Section_Data_s));
  1223.     if (cursect == NULL) return(NULL);
  1224.  
  1225.         if (dbg->de_debug_sects == NULL) {
  1226.         dbg->de_debug_sects = dbg->de_last_debug_sect = cursect;
  1227.         }
  1228.         else {
  1229.             dbg->de_last_debug_sect->ds_next = cursect;
  1230.         dbg->de_last_debug_sect = cursect;
  1231.         }
  1232.     dbg->de_n_debug_sect++;
  1233.  
  1234.     cursect->ds_elf_sect_no = elfsectno;
  1235.     }
  1236.     else 
  1237.     cursect = dbg->de_last_debug_sect;
  1238.  
  1239.     if (cursect->ds_data == NULL) { 
  1240.         cursect->ds_data = (char *)
  1241.         _dwarf_p_get_alloc(dbg, nbytes > CHUNK_SIZE ? nbytes : CHUNK_SIZE); 
  1242.     if (cursect->ds_data == NULL) return(NULL);
  1243.  
  1244.         cursect->ds_nbytes = nbytes; 
  1245.         return((char *)cursect->ds_data);
  1246.     }
  1247.     else {            
  1248.             /* There is enough space in the current buffer */
  1249.         cursect->ds_nbytes += nbytes;
  1250.         return((char *)(cursect->ds_data + cursect->ds_nbytes - nbytes));
  1251.     }
  1252. }
  1253.  
  1254.  
  1255. /*--------------------------------------------------------------------
  1256.     Get a pointer at byteoff offset in the buffer 
  1257. ----------------------------------------------------------------------*/
  1258. char *
  1259. _dwarf_pro_nth_byteoff(
  1260.     Dwarf_P_Debug dbg,
  1261.     int byteoff)
  1262. {
  1263.     /* functions incomplete, may also need a elf section number */
  1264.     Dwarf_P_Section_Data cursect;
  1265.  
  1266.     cursect = dbg->de_debug_sects;
  1267.  
  1268.     if (cursect == NULL) 
  1269.         return NULL;
  1270.     
  1271.     for (; cursect != NULL; cursect = cursect->ds_next) {
  1272.         if (byteoff >= cursect->ds_nbytes) {
  1273.         byteoff -= cursect->ds_nbytes;
  1274.         continue;
  1275.         }
  1276.         return (char *)(cursect->ds_data + byteoff);
  1277.     }
  1278.     return NULL;
  1279. }
  1280.  
  1281. /*------------------------------------------------------------
  1282.     Given address advance and line advance, it gives 
  1283.     either special opcode, or a number < 0
  1284. ------------------------------------------------------------*/
  1285. static int
  1286. _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv)
  1287. {
  1288.     int opc ;
  1289.  
  1290.     addr_adv = addr_adv/MIN_INST_LENGTH;
  1291.     if (line_adv == 0 && addr_adv == 0)
  1292.         return OPC_INCS_ZERO;
  1293.     if (line_adv >= LINE_BASE && line_adv < LINE_BASE + LINE_RANGE) {
  1294.         opc = (line_adv - LINE_BASE) + (addr_adv*LINE_RANGE) + OPCODE_BASE;
  1295.         if (opc > 255) return OPC_OUT_OF_RANGE;
  1296.         return opc;
  1297.     }
  1298.     else 
  1299.         return LINE_OUT_OF_RANGE;
  1300. }
  1301.  
  1302. /*-----------------------------------------------------------------------
  1303.     Handles abbreviations. It takes a die, searches through 
  1304.     current list of abbreviations for matching one. If it
  1305.     finds one, it returns a pointer to it, and if it doesnt, 
  1306.     it returns a new one. Upto the user of this function to 
  1307.     link it up to the abbreviation head. If its a new one,
  1308.     abb_idx has 0.
  1309. -----------------------------------------------------------------------*/
  1310. static Dwarf_P_Abbrev 
  1311. _dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head)
  1312. {
  1313.     Dwarf_P_Abbrev curabbrev;
  1314.     Dwarf_P_Attribute  curattr;
  1315.     int idx;
  1316.     int res1, res2;
  1317.     int nattrs;
  1318.     int match;
  1319.     Dwarf_Word *forms, *attrs;    /* holds attr and form names */
  1320.  
  1321.     curabbrev = head;
  1322.     while (curabbrev) {
  1323.         if ((die->di_tag == curabbrev->abb_tag) &&
  1324.            ((die->di_child != NULL && curabbrev->abb_children == DW_CHILDREN_yes) || 
  1325.            (die->di_child == NULL && curabbrev->abb_children == DW_CHILDREN_no)) &&
  1326.            (die->di_n_attr == curabbrev->abb_n_attr)) {    /* chance of a match */
  1327.         curattr = die->di_attrs;
  1328.         match = 1;    /* assume match found */
  1329.         while (match && curattr) {
  1330.             res1 = _dwarf_pro_match_attr(curattr, curabbrev, curabbrev->abb_n_attr);
  1331.             if (res1 == 0) 
  1332.             match = 0;
  1333.             curattr = curattr->ar_next;
  1334.         }
  1335.         if (match == 1) return curabbrev;
  1336.         }
  1337.         curabbrev = curabbrev->abb_next;
  1338.     }
  1339.  
  1340.     /* no match, create new abbreviation */
  1341.     if (die->di_n_attr != 0) {
  1342.         forms = (Dwarf_Word *)
  1343.             _dwarf_p_get_alloc(NULL,sizeof(Dwarf_Word)*die->di_n_attr);
  1344.         if (forms == NULL) return NULL;
  1345.         attrs = (Dwarf_Word *)
  1346.             _dwarf_p_get_alloc(NULL,sizeof(Dwarf_Word)*die->di_n_attr);
  1347.         if (attrs == NULL) return NULL;
  1348.     }
  1349.     nattrs = 0;
  1350.     curattr = die->di_attrs;
  1351.     while (curattr) {
  1352.         attrs[nattrs] = curattr->ar_attribute;
  1353.         forms[nattrs] = curattr->ar_attribute_form;
  1354.         nattrs++;
  1355.         curattr = curattr->ar_next;
  1356.     }
  1357.  
  1358.     curabbrev = (Dwarf_P_Abbrev)
  1359.         _dwarf_p_get_alloc(NULL,sizeof(struct Dwarf_P_Abbrev_s));
  1360.     if (curabbrev == NULL) return NULL;
  1361.  
  1362.     if (die->di_child == NULL) 
  1363.         curabbrev->abb_children = DW_CHILDREN_no;
  1364.     else
  1365.         curabbrev->abb_children = DW_CHILDREN_yes;
  1366.     curabbrev->abb_tag = die->di_tag;
  1367.     curabbrev->abb_attrs = attrs;
  1368.     curabbrev->abb_forms = forms;
  1369.     curabbrev->abb_n_attr = die->di_n_attr;
  1370.     curabbrev->abb_idx = 0;
  1371.     curabbrev->abb_next = NULL;
  1372.  
  1373.     return curabbrev;
  1374. }
  1375.  
  1376. /*------------------------------------------------------------------
  1377.     Tries to see if given attribute and form combination 
  1378.     exists in the given abbreviation
  1379. -------------------------------------------------------------------*/
  1380. static int 
  1381. _dwarf_pro_match_attr(
  1382.     Dwarf_P_Attribute attr,
  1383.     Dwarf_P_Abbrev abbrev, 
  1384.     int no_attr)
  1385.  
  1386. {
  1387.     int i;
  1388.     int found = 0;
  1389.  
  1390.     for (i = 0; i < no_attr; i++) {
  1391.         if (attr->ar_attribute == abbrev->abb_attrs[i] &&
  1392.             attr->ar_attribute_form == abbrev->abb_forms[i]) {
  1393.             found = 1;
  1394.             break;
  1395.         }
  1396.     }
  1397.     return found;
  1398. }
  1399.  
  1400. /*--------------------------------------------------------------------
  1401.     allocate a new relocation linked list element, alongwith an
  1402.     appropriate relocation record pointer
  1403. ----------------------------------------------------------------------*/
  1404. static Dwarf_P_Rel 
  1405. _dwarf_pro_get_new_relrec(Dwarf_P_Debug dbg)
  1406. {
  1407.     Dwarf_P_Rel rel;
  1408.  
  1409.     rel = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Rel_s));
  1410.     if (rel == NULL) return NULL;
  1411.  
  1412.     if (IS_64BIT(dbg)) {
  1413.         dr_rel64(rel) = (Elf64_Rel *)
  1414.                  _dwarf_p_get_alloc(dbg,sizeof(Elf64_Rel));
  1415.         if (dr_rel64(rel) == NULL) return NULL;
  1416.     }
  1417.     else {
  1418.         dr_rel32(rel) = (Elf32_Rel *)
  1419.                  _dwarf_p_get_alloc(dbg, sizeof(Elf32_Rel));
  1420.         if (dr_rel32(rel) == NULL) return NULL;
  1421.     }
  1422.     return rel;
  1423. }
  1424.  
  1425. static int
  1426. _dwarf_pro_rel_info(
  1427.     Dwarf_P_Debug dbg,
  1428.     Dwarf_P_Rel relrec,
  1429.     Dwarf_Unsigned offset,
  1430.     Dwarf_Word symidx,
  1431.     Dwarf_Ubyte type) 
  1432. {
  1433.     int nbytes = 0;
  1434.     if (IS_64BIT(dbg)) {
  1435.         dr_rel64(relrec)->r_offset = offset;
  1436.         Set_REL64_info (*dr_rel64(relrec), symidx, type);
  1437.         nbytes += sizeof(Elf64_Rel);
  1438.     }
  1439.     else {
  1440.         dr_rel32(relrec)->r_offset = offset;
  1441.         Set_REL32_info ( *dr_rel32(relrec), symidx, type );
  1442.         nbytes += sizeof(Elf32_Rel);
  1443.     }
  1444.  
  1445.     return nbytes;
  1446. }
  1447.  
  1448. static int 
  1449. _dwarf_pro_write_reloc_section(
  1450.     Dwarf_P_Debug dbg,
  1451.     Dwarf_P_Rel rel_head,
  1452.     int relsectno,
  1453.     int rel_nbytes,
  1454.     Dwarf_Error *error)
  1455. {
  1456.     char *data;
  1457.  
  1458.     if (rel_nbytes != 0) {
  1459.         GET_NEW_CHUNK(dbg,relsectno,data,rel_nbytes,&error);
  1460.         while (rel_head) {
  1461.         if (IS_64BIT(dbg)) {
  1462.             memcpy((void *)data, (const void *)dr_rel64(rel_head), 
  1463.             sizeof(Elf64_Rel));
  1464.             data += sizeof(Elf64_Rel);
  1465.         }
  1466.         else {
  1467.             memcpy((void *)data, (const void *)dr_rel32(rel_head), 
  1468.             sizeof(Elf32_Rel));
  1469.             data += sizeof(Elf32_Rel);
  1470.         }
  1471.         rel_head = rel_head->dr_next;
  1472.         }
  1473.     }
  1474.     return 0;
  1475. }
  1476.